package com.huilian.iotbox.admin.wap.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.huilian.iotbox.admin.wap.dao.*;
import com.huilian.iotbox.admin.wap.security.enums.JwtRedisEnum;
import com.huilian.iotbox.admin.wap.security.jwt.util.JwtTokenUtil;
import com.huilian.iotbox.admin.wap.security.properties.WapSecurityProperties;
import com.huilian.iotbox.admin.wap.service.*;
import com.huilian.iotbox.data.common.RedisHelper;
import com.huilian.iotbox.data.common.RedisKey;
import com.huilian.iotbox.data.common.ServerResponse;
import com.huilian.iotbox.data.dao.UserCommonDao;
import com.huilian.iotbox.data.dao.UserRoleDao;
import com.huilian.iotbox.data.dto.*;
import com.huilian.iotbox.data.enums.*;
import com.huilian.iotbox.data.po.*;
import com.huilian.iotbox.data.service.AppletOrOfficialAccountCommonService;
import com.huilian.iotbox.data.service.SystemConfigService;
import com.huilian.iotbox.data.service.UserAttributeCommonService;
import com.huilian.iotbox.data.utils.Util;
import com.huilian.iotbox.data.vo.*;
import com.huilian.security.sms.SmsCodeSender;
import com.huilian.tool.applet.wechat.service.WeChatAppletService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 少凡
 * @date 2020/2/23 10:38
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserCommonDao userCommonDao;
    @Resource
    private RedisHelper redisHelper;
    @Autowired
    private UserRoleDao userRoleDao;
    @Autowired
    private BrandInfoDao brandInfoDao;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Resource
    private CommodityDao commodityDao;
    @Autowired
    private SmsCodeSender smsCodeSender;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private MerchantStoreDao merchantStoreDao;
    @Autowired
    private CommodityGroupDao commodityGroupDao;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private WeChatAppletService weChatAppletService;
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private UserPermissionService userPermissionService;
    @Autowired
    private WapSecurityProperties wapSecurityProperties;
    @Autowired
    private CustomerServiceInfoDao customerServiceInfoDao;
    @Autowired
    private CommodityStoreUpDownDao commodityStoreUpDownDao;
    @Autowired
    private UserAttributeCommonService userAttributeCommonService;
    @Autowired
    private RedisTemplate<String, Serializable> redisCacheTemplate;
    @Autowired
    private AppletOrOfficialAccountCommonService appletOrOfficialAccountCommonService;

    @Override
    public ServerResponse login(User param) {
        final Integer count = userCommonDao.checkUserName(param.getUsername(), UserStatusEnum.WRITE_OFF.getCode());
        if (count == 0) {
            return ServerResponse.createByErrorMessage(param.getUsername() + "账号未注册");
        } else if (count > 1) {
            return ServerResponse.createByErrorMessage(param.getUsername() + "账号存在多个，请联系平台客服处理");
        }

        final User user = userCommonDao.getByUsername(param, UserStatusEnum.WRITE_OFF.getCode());
        boolean matches = passwordEncoder.matches(param.getPassword(), user.getPassword());
        if (!matches) {
            return ServerResponse.createByErrorMessage("账号或密码错误");
        }
        ServerResponse serverResponse = this.generateToken(user);
        if (!serverResponse.getIsSuccess()) {
            return serverResponse;
        }

        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setLoginCount(user.getLoginCount() + 1);
        userCommonDao.update(updateUser);

        UserRole userRole = userRoleService.findOneUserRoleByUserId(user.getId());

        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user, userVo);
        userVo.setRoleId(userRole.getRoleId());

        return ServerResponse.createBySuccess(userVo);
    }

    private ServerResponse generateToken(User user) {
        if (!org.springframework.util.StringUtils.isEmpty(user.getLockStatus()) && user.getLockStatus()) {
            return ServerResponse.createByErrorMessage("账号被锁定");
        }
        if (user.getStatus().equals(UserStatusEnum.ENABLED.getCode())) {
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user, null, null);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            final String randomKey = jwtTokenUtil.getRandomKey();
            String userId = user.getId().toString();

            final String token = jwtTokenUtil.generateToken(userId, randomKey);
            // 存到redis
            redisCacheTemplate.opsForValue().set(JwtRedisEnum.getTokenKey(userId, randomKey), token, wapSecurityProperties.getJwt().getExpiration(), TimeUnit.SECONDS);

            // 将认证信息存到redis，方便后期业务用，也方便 JwtAuthenticationTokenFilter用
            redisCacheTemplate.opsForValue().set(JwtRedisEnum.getAuthenticationKey(userId, randomKey), JSON.toJSONString(authentication), wapSecurityProperties.getJwt().getExpiration(), TimeUnit.SECONDS);
            user.setPassword(null);
            user.setOperatePassword(null);
            user.setToken(token);
            return ServerResponse.createBySuccess(user);
        }
        return ServerResponse.createByErrorMessage("请稍后重试");
    }

    @Override
    public ServerResponse getListByAgencyId(UserInfo userInfo) {
        List<User> list = userCommonDao.getListByAgencyId(userInfo);
        return ServerResponse.createBySuccess(list);
    }

    @Override
    @Transactional
    public ServerResponse add(User user) {
        ServerResponse response = checkIsExist(user.getMobile(), user.getUsername());
        if (response.getIsSuccess()) {

            user.setPassword(passwordEncoder.encode(user.getPassword()));
            user.setVersion(0);
            Integer result = userCommonDao.insert(user);

            UserRole userRole = new UserRole();

            for (RoleVo roleVo : user.getRoles()) {
                if (roleVo.getChecked()) {
                    userRole.setRoleId(roleVo.getValue());
                    userRole.setUserId(user.getId());
                    userRoleService.add(userRole);
                }
            }

            if (result == 1) {
                return ServerResponse.createBySuccess();
            } else {
                return ServerResponse.createByError("用户添加失败");
            }
        } else {
            return response;
        }

    }


    @Override
    @Transactional
    public ServerResponse update(User user) {

        UserRole userRole = new UserRole();

        if (user.getRoles() != null) {

            for (RoleVo roleVo : user.getRoles()) {

                userRole.setUserId(user.getId());
                userRole.setRoleId(roleVo.getValue());

                Integer count = userRoleService.findByUserIdAndRoleId(userRole);

                if (roleVo.getChecked() && count == 0) {
                    userRoleService.add(userRole);
                } else if (!roleVo.getChecked() && count != 0) {
                    userRoleService.delete(userRole);
                }
            }
        }

        Integer result = userCommonDao.update(user);
        if (result == 1) {
            String key = String.format(RedisKey.WAP_USERINFO, user.getId());
            redisCacheTemplate.delete(key);
            return ServerResponse.createBySuccess();
        } else {
            return ServerResponse.createByError("用户更新失败");
        }
    }

    @Override
    public ServerResponse delete(Integer userId) {
        Integer result = userCommonDao.delete(userId);
        if (result == 1) {
            return ServerResponse.createBySuccess();
        } else {
            return ServerResponse.createByError("用户更新失败");
        }
    }

    @Override
    public ServerResponse checkIsExist(String mobile, String username) {

        if (!StringUtils.isBlank(mobile)) {
            if (checkMobile(mobile)) {
                return ServerResponse.createByErrorMessage("手机号已存在");
            }
        }

        if (!StringUtils.isBlank(username)) {
            if (checkUserName(username)) {
                return ServerResponse.createByErrorMessage("登录账号已存在");
            }
        }
        return ServerResponse.createBySuccess();
    }

    @Override
    public UserInfo getLoginUserInfo(HttpServletRequest request) {
        User user = jwtTokenUtil.getUserInfoFromReq(request);
        String userId = user.getId().toString();
        String key = String.format(RedisKey.WAP_USERINFO, userId);
        UserInfo userInfo = (UserInfo) redisCacheTemplate.opsForValue().get(key);
        if (userInfo == null) {
            userInfo = userCommonDao.getUserInfo(userId);
            if (!ObjectUtils.isEmpty(userInfo.getRoles())) {
                userInfo.setRoleId(userInfo.getRoles().get(0).getRoleId());
            }
            // 如果是员工就获取他管理的场地 员工的状态是5
            if (RoleEnum.SUB_ACCOUNT.getRoleId().equals(userInfo.getRoleId())) {
//                UserStore userStore = new UserStore();
//                userStore.setUserId(Integer.parseInt(userId));
//                userStore.setStatus(true);
//                final List<Integer> list = userStoreService.getUserStore(userStore);
//                userInfo.getStoreIdList().addAll(list);

                UserDto uDto = new UserDto();
                uDto.setAttributeId(AttributeEnum.SUB_ACCOUNT_ADMIN_STORE.getCode());
                uDto.setUserId(Integer.parseInt(userId));
                final List<UserAttribute> list = userAttributeCommonService.findUserAttributeByUserIdList(uDto);
                if (!org.springframework.util.StringUtils.isEmpty(list) && list.size() > 0) {
                    userInfo.getStoreIdList().addAll(list.stream()
                            .map(UserAttribute::getMerchantStoreId)
                            .collect(Collectors.toList()));
                }
            }
            redisCacheTemplate.opsForValue().set(key, userInfo, 24, TimeUnit.HOURS);
        }
        return userInfo;
    }

    @Override
    public ServerResponse smsCode(UserDto userDto, String templateId) {
        // 判断登录账户商户是否唯一
        if (userDto.getVerifyType() != null) {
            if (this.checkMobile(userDto.getMobile())) {
                return ServerResponse.createByErrorMessage("该手机号已存在请更换新的号码");
            }
        } else {
            if (!this.checkUserName(userDto.getMobile())) {
                return ServerResponse.createByErrorMessage("手机号有误，请重新输入");
            }
        }

        if (!ObjectUtils.isEmpty(userDto) && !StringUtils.isEmpty(userDto.getMobile())) {
            String key = RedisKey.REGISTER_SMSCODE + userDto.getMobile();
            String s = (String) redisCacheTemplate.opsForValue().get(key + "EXPR");
            if (!ObjectUtils.isEmpty(s)) {
                return ServerResponse.createByErrorMessage("验证码发送频繁！");
            }
            redisCacheTemplate.delete(key);

            return sendSms(key, userDto, templateId);
        }
        return ServerResponse.createBySuccess();
    }

    /**
     * 发送短信验证码
     *
     * @param key
     * @param userDto
     * @param templateId
     * @return
     */
    private ServerResponse sendSms(String key, UserDto userDto, String templateId) {
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            sb.append(random.nextInt(10));
        }
        log.info("验证码是: {}", sb);
        com.huilian.security.sms.common.ServerResponse serverResponse = smsCodeSender.send(userDto.getMobile(), sb.toString(), templateId);

        if (serverResponse.getIsSuccess()) {
            redisCacheTemplate.opsForValue().set(key, sb.toString(), 30, TimeUnit.MINUTES);
            redisCacheTemplate.opsForValue().set(key + "EXPR", "111", 1, TimeUnit.MINUTES);
            return ServerResponse.createBySuccess("已向" + Util.repPhone(userDto.getMobile()) + "手机号成功发送验证码");
        }
        return ServerResponse.createByErrorMessage(serverResponse.getMsg());
    }

    /**
     * 自定义手机号注册
     *
     * @param userDto
     * @return
     */
    @Override
    @Transactional
    public ServerResponse register(UserDto userDto) {
        ServerResponse serverResponse = this.checkIsExist(userDto.getMobile(), userDto.getUsername());
        if (!serverResponse.getIsSuccess()) {
            return serverResponse;
        }
        log.info("注册运营商上级机构: {},手机号: {}", userDto.getAgencyId(), userDto.getMobile());
        if (org.springframework.util.StringUtils.isEmpty(userDto.getAgencyId())) {
            userDto.setAgencyId(1);
        }

        //判断验证码
        String key = RedisKey.REGISTER_SMSCODE + userDto.getMobile();
        String s = (String) redisCacheTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(s)) {
            return ServerResponse.createByErrorMessage("验证码不存在");
        } else {
            if (!s.equals(userDto.getSmsCode())) {
                return ServerResponse.createByErrorMessage("验证码错误");
            }
        }

        if (!org.springframework.util.StringUtils.isEmpty(userDto.getKey())) {
            User u = (User) redisCacheTemplate.opsForValue().get(String.format(RedisKey.WAP_USER_TEMPORARY_WX_INFO, userDto.getKey()));
            if (!org.springframework.util.StringUtils.isEmpty(u)) {
                userDto.setNickname(u.getName());
                userDto.setOpenId(u.getOpenId());
                userDto.setUnionId(u.getUnionId());
            }
        }


        User user = this.registerUser(userDto);
        ServerResponse response = generateToken(user);
        if (!response.getIsSuccess()) {
            return response;
        }
        User u = (User) response.getData();

        User nu = new User();
        nu.setToken(u.getToken());

        redisCacheTemplate.delete(key);
        return ServerResponse.createBySuccess(nu);
    }

    /**
     * 运营商注册公共方法
     *
     * @param userDto
     */
    @Override
    public User registerUser(UserDto userDto) {

        SystemConfig systemConfig = systemConfigService.findOneSystemConfigById(1);
        User user = new User();
        String password;
        if (!StringUtils.isEmpty(userDto.getPassword())) {
            password = passwordEncoder.encode(userDto.getPassword());
        } else {
            password = passwordEncoder.encode("123456");
        }
        user.setPassword(password);
        user.setOperatePassword(password);
        user.setNickname(userDto.getNickname());
        user.setMobile(userDto.getMobile());
        user.setHeadImgUrl(userDto.getHeadImgUrl());
        user.setUsername(userDto.getMobile());
        user.setName(userDto.getName());
        user.setAgencyId(userDto.getAgencyId());
        user.setOpenId(userDto.getOpenId());
        user.setUnionId(userDto.getUnionId());
        user.setStatus(AccountStatusEnum.NORMAL.getCode());
        user.setLockStatus(false);
        user.setVersion(0);
        user.setReceiptType(MchTypeEnum.OWN.getCode());
        user.setWelfareReturnCoinSum(systemConfig.getDistributeWelfareToMemberByMaxCoin());
        user.setLoginCount(1);
        user.setLastLoginTime(new Date());
        userCommonDao.insert(user);
        UserRole userRole = new UserRole();
        userRole.setRoleId(RoleEnum.MERCHANT.getRoleId());
        userRole.setUserId(user.getId());
        userRoleService.add(userRole);

        // 默认客服信息添加
        BrandInfoDto brandInfoDto = new BrandInfoDto();
        brandInfoDto.setUserId(user.getId());
        brandInfoDto.setServiceMobilePhone(userDto.getMobile());
        brandInfoDao.insert(brandInfoDto);
        user.setBrandInfoId(brandInfoDto.getId());
        this.addSitePackage(user);
        return user;
    }

    public void addSitePackage(User user) {
        //默认添加场地
        MerchantStoreDto merchantStoreDto = new MerchantStoreDto();
        merchantStoreDto.setMchId(null);
        merchantStoreDto.setUserId(user.getId());
        merchantStoreDto.setStoreName("默认场地（可修改名称）");
        merchantStoreDto.setProvince("北京");
        merchantStoreDto.setCity("北京市");
        merchantStoreDto.setDistrict("东城区");
        merchantStoreDto.setAddress("天安门广场");
        merchantStoreDto.setStatus(MerchantStoreStatusEnum.NORMAL.getCode());
        merchantStoreDto.setAutomaticRefund(false);
        merchantStoreDto.setAutomaticCoin(false);
        merchantStoreDto.setFillInMemberInfo(false);
        merchantStoreDto.setDefaultStatus(true);
        merchantStoreDao.defaultAddMerchantStore(merchantStoreDto);

        CustomerServiceInfoDto customerServiceInfoDto = new CustomerServiceInfoDto();
        customerServiceInfoDto.setBrandInfoId(user.getBrandInfoId());
        customerServiceInfoDto.setMerchantStoreId(merchantStoreDto.getId());
        customerServiceInfoDto.setServiceMobilePhone(user.getMobile());
        customerServiceInfoDao.insertServiceMobilePhone(customerServiceInfoDto);

        //添加“游戏币套餐”分组
        CommodityGroup commodityGroup = new CommodityGroup();
        commodityGroup.setUserId(user.getId());
        commodityGroup.setName("游戏币套餐");
        commodityGroup.setType(CommodityGroupTypeEnum.GAME_COIN.getCode());
        commodityGroupDao.insert(commodityGroup);

        //创建套餐
        int[] price = {1, 5, 10, 20, 50, 100};
        Commodity commodity = new Commodity();
        commodity.setUserId(user.getId());
        commodity.setType(CommodityTypeEnum.REGULAR.getCode());
        commodity.setCommodityGroupId(commodityGroup.getId());
        commodity.setIsDefault(true);
        commodity.setRecommend(true);
        commodity.setHide(true);
        commodity.setPosTerminal(true);
        commodity.setGiveCoin(0);
        commodity.setClientTerminal(true);
        int sort = 1;
        for (int i = 0; i < price.length; i++) {
            commodity.setSort(sort + i);
            commodity.setRetailPrice(new BigDecimal(price[i]));
            commodity.setRechargeCoin(price[i]);
            commodity.setName(price[i] + "枚游戏币");
            commodityDao.insert(commodity);
            //添加套餐上架表
            CommodityStoreUpDownDto cupd = new CommodityStoreUpDownDto();
            cupd.setCommodityId(commodity.getId());
            cupd.setMerchantStoreId(merchantStoreDto.getId());
            cupd.setUserId(user.getId());
            cupd.setRetailPrice(new BigDecimal(price[i]));
            cupd.setStatus(CommodityStoreUpDownEnum.GROUNDING.getCode());
            cupd.setClientTerminal(true);
            cupd.setPosTerminal(true);
            commodityStoreUpDownDao.insert(cupd);
        }

    }

    /**
     * 在小程序获取手机号注册（没验证码）
     *
     * @param userDto
     * @return
     */
    @Override
    public ServerResponse registerByAppletMobile(UserDto userDto) {
        ServerResponse serverResponse = this.checkIsExist(userDto.getMobile(), userDto.getUsername());
        if (!serverResponse.getIsSuccess()) {
            return serverResponse;
        }
        log.info("注册运营商上级机构: {},手机号: {}", userDto.getAgencyId(), userDto.getMobile());
        if (org.springframework.util.StringUtils.isEmpty(userDto.getAgencyId())) {
            userDto.setAgencyId(1);
        }


        final String key = String.format(RedisKey.APPLET_WAP_TEMPORARY_SESSION_KEY, userDto.getSessionKeyId());
        log.info("key:::" + key);
        Map<String, String> map = (Map<String, String>) redisCacheTemplate.opsForValue().get(key);
        userDto.setUnionId(map.get("unionId"));

        userDto.setUsername(userDto.getMobile());
        User user = this.registerUser(userDto);
        ServerResponse response = generateToken(user);
        if (!response.getIsSuccess()) {
            return response;
        }
        User u = (User) response.getData();

        User nu = new User();
        nu.setToken(u.getToken());
        return ServerResponse.createBySuccess(nu);
    }

    @Override
    public ServerResponse updateMobile(UserDto userDto) {
        //判断验证码
        if (userDto.getSmsCode() != null && !userDto.getSmsCode().equals("")) {
            String key = RedisKey.REGISTER_SMSCODE + userDto.getMobile();
            String s = (String) redisCacheTemplate.opsForValue().get(key);
            if (StringUtils.isEmpty(s)) {
                return ServerResponse.createByErrorMessage("验证码不存在");
            } else {
                if (!s.equals(userDto.getSmsCode())) {
                    return ServerResponse.createByErrorMessage("验证码错误");
                }
            }
            redisCacheTemplate.delete(key);
        }
        User user = userCommonDao.getUserId(userDto.getId());
        if (StringUtils.isEmpty(user.getUsername())) {
            userDto.setUsername(userDto.getMobile());
        }
        if (StringUtils.isEmpty(user.getPassword())) {
            userDto.setPassword(passwordEncoder.encode(userDto.getMobile()));
        }
        if (StringUtils.isEmpty(user.getOperatePassword())) {
            userDto.setOperatePassword(passwordEncoder.encode(userDto.getMobile()));
        }
        return ServerResponse.createBySuccess(userCommonDao.updateMobileAndPassword(userDto));
    }

    @Override
    public ServerResponse findById(Integer id) {
        return ServerResponse.createBySuccess(userCommonDao.findById(id));
    }

    @Override
    public User findUserById(Integer id) {
        return userCommonDao.findUserById(id);
    }

    @Override
    public ServerResponse findUserBalance(UserInfo userInfo) {
        return ServerResponse.createBySuccess(userCommonDao.findUserBalance(userInfo.getId()));

    }

    @Override
    public Integer updateUserReceiptType(UserDto userDto) {
        User user = new User();
        user.setId(userDto.getId());
        user.setReceiptType(userDto.getReceiptType());
        Integer count = userCommonDao.update(user);
        if (count > 0) {
            String key = String.format(RedisKey.RECEIPT_TYPE, user.getId());
            redisCacheTemplate.delete(key);
        }
        return count;
    }

    @Override
    public UserVo findUserReceiptType(UserInfo userInfo) {
        String key = String.format(RedisKey.RECEIPT_TYPE, userInfo.getId());
        String receiptType = (String) redisCacheTemplate.opsForValue().get(key);
        UserVo userVo = new UserVo();
        if (StringUtils.isEmpty(receiptType)) {
            Integer userId = userInfo.getId();
            if (RoleEnum.SUB_ACCOUNT.getRoleId().equals(userInfo.getRoleId())) {
                userId = userInfo.getParentId();
            }
            userVo = userCommonDao.findUser(userId);
            if (userVo.getReceiptType() != null) {
                redisCacheTemplate.opsForValue().set(key, userVo.getReceiptType().toString());
            }
            return userVo;
        } else {
            userVo.setReceiptType(Integer.parseInt(receiptType));
            return userVo;
        }

    }

    @Override
    public ServerResponse updatePwd(UserDto userDto) {
        User user = userCommonDao.findUserByLoginUserName(userDto.getUserInfo().getUsername(), UserStatusEnum.WRITE_OFF.getCode());
        boolean isMatches = passwordEncoder.matches(userDto.getPassword(), user.getPassword());
        if (isMatches) {
            User userPwd = new User();
            userPwd.setPassword(passwordEncoder.encode(userDto.getNewPassword()));
            userPwd.setId(userDto.getUserInfo().getId());
            Integer count = userCommonDao.updatePwd(userPwd);
            if (count > 0) {
                return ServerResponse.createBySuccess();
            } else {
                return ServerResponse.createByErrorMessage("密码修改失败");
            }
        } else {
            return ServerResponse.createByErrorMessage("原密码不正确，请重新输入");
        }
    }

    @Override
    public ServerResponse updateOperatePassword(UserDto userDto) {
        User user = userCommonDao.findUserByLoginUserName(userDto.getUserInfo().getUsername(), UserStatusEnum.WRITE_OFF.getCode());
        boolean isMatches = passwordEncoder.matches(userDto.getOperatePassword(), user.getOperatePassword());
        if (isMatches) {
            User userPwd = new User();
            userPwd.setOperatePassword(passwordEncoder.encode(userDto.getNewPassword()));
            userPwd.setId(userDto.getUserInfo().getId());
            Integer count = userCommonDao.updatePwd(userPwd);
            if (count > 0) {
                return ServerResponse.createBySuccess();
            } else {
                return ServerResponse.createByErrorMessage("操作密码修改失败");
            }
        } else {
            return ServerResponse.createByErrorMessage("原操过密码不正确，请重新输入");
        }
    }

    @Override
    public User queryById(int id) {
        return userCommonDao.findUserById(id);
    }


    @Override
    public ServerResponse resetPwd(UserDto userDto) {
        //判断验证码
        String key = RedisKey.REGISTER_SMSCODE + userDto.getMobile();
        String smsCode = (String) redisCacheTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(smsCode)) {
            return ServerResponse.createByErrorMessage("验证码不存在");
        } else {
            if (!smsCode.equals(userDto.getSmsCode())) {
                return ServerResponse.createByErrorMessage("验证码错误");
            }
        }
        redisCacheTemplate.delete(key);
        User user = userCommonDao.findUserByLoginUserName(userDto.getMobile(), UserStatusEnum.WRITE_OFF.getCode());
        User userPwd = new User();
        if ("oper".equals(userDto.getOperType())) {
            userPwd.setOperatePassword(passwordEncoder.encode(userDto.getNewPassword()));
        } else {
            userPwd.setPassword(passwordEncoder.encode(userDto.getNewPassword()));
        }
        userPwd.setId(user.getId());
        Integer count = userCommonDao.updatePwd(userPwd);
        if (count > 0) {
            return ServerResponse.createBySuccess();
        } else {
            return ServerResponse.createByErrorMessage("密码修改失败");
        }
    }

    @Override
    public Integer updateUser(User user) {
        return userCommonDao.update(user);
    }

    private boolean checkUserName(String username) {
        Integer count = userCommonDao.checkUserName(username, UserStatusEnum.WRITE_OFF.getCode());
        if (count > 0) {
            return true;
        }
        return false;
    }

    private boolean checkMobile(String mobile) {
        Integer count = userCommonDao.checkMobile(mobile, UserStatusEnum.WRITE_OFF.getCode());
        if (count > 0) {
            return true;
        }
        return false;
    }

    @Override
    public UserInfo getNewUserInfo(HttpServletRequest request) {
        User user = jwtTokenUtil.getUserInfoFromReq(request);
        String userId = user.getId().toString();
        UserInfo userInfo = userCommonDao.getUserInfo(userId);
        return userInfo;
    }

    @Override
    public ServerResponse loginPwdReset(UserDto userDto, HttpServletRequest request) {
        User user = userCommonDao.findById(userDto.getUserInfo().getId());
        if (userDto.getPassword().equals(userDto.getNewPassword())) {
            return ServerResponse.createByErrorMessage("新密码不能与旧密码一样！");
        }
        if (passwordEncoder.matches(userDto.getPassword(), user.getPassword())) {
            User u = new User();
            u.setId(user.getId());
            u.setPassword(passwordEncoder.encode(userDto.getNewPassword()));
            userCommonDao.updatePwd(u);
            //删除 商家端 的登录token
            Set<String> wapTokenKeys = redisHelper.keys(JwtRedisEnum.getTokenKey(userDto.getUserInfo().getId().toString(), "*"));
            for (String key : wapTokenKeys) {
                Boolean delete = redisCacheTemplate.delete(key);
            }

            Set<String> wapAuthKeys = redisHelper.keys(JwtRedisEnum.getAuthenticationKey(userDto.getUserInfo().getId().toString(), "*"));
            for (String key : wapAuthKeys) {
                Boolean delete = redisCacheTemplate.delete(key);
            }

            //删除 POS 的登录token
            Set<String> posKeys = redisHelper.keys("iot_pos:jwt:" + userDto.getUserInfo().getId() + ":*");
            for (String key : posKeys) {
                Boolean delete = redisCacheTemplate.delete(key);
            }
        } else {
            return ServerResponse.createByErrorMessage("旧密码不正确！");
        }
        return ServerResponse.createBySuccess();
    }

    @Override
    public ServerResponse operatePwdReset(UserDto userDto) {
        User user = userCommonDao.findById(userDto.getUserInfo().getId());
        if (userDto.getPassword().equals(userDto.getNewPassword())) {
            return ServerResponse.createByErrorMessage("新密码不能与旧密码一样！");
        }
        if (passwordEncoder.matches(userDto.getPassword(), user.getOperatePassword())) {
            User u = new User();
            u.setId(user.getId());
            u.setOperatePassword(passwordEncoder.encode(userDto.getNewPassword()));
            userCommonDao.updatePwd(u);
        } else {
            return ServerResponse.createByErrorMessage("旧密码不正确！");
        }
        return ServerResponse.createBySuccess();
    }

    @Override
    public ServerResponse getResetSmsCode(UserDto userDto, String templateid) {
        // 判断登录账户商户是否唯一
        if (!this.checkUserName(userDto.getMobile())) {
            return ServerResponse.createByErrorMessage("手机号有误，找不到对应的账号，请重新输入");
        }
        String key = RedisKey.RESET_SMS_CODE + userDto.getMobile();
        String s = (String) redisCacheTemplate.opsForValue().get(key + "EXPR");
        redisCacheTemplate.opsForValue().getOperations().getExpire(key + "EXPR");
        if (!ObjectUtils.isEmpty(s)) {
            Long i = redisCacheTemplate.opsForValue().getOperations().getExpire(key + "EXPR");
            return ServerResponse.createByErrorMessage("验证码发送频繁！请" + i + "秒后重试");
        }
        redisCacheTemplate.delete(key);
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            sb.append(random.nextInt(10));
        }
        log.info("验证码是: {}", sb);
        com.huilian.security.sms.common.ServerResponse serverResponse = smsCodeSender.send(userDto.getMobile(), sb.toString(), templateid);

        if (serverResponse.getIsSuccess()) {
            redisCacheTemplate.opsForValue().set(key, sb.toString(), 30, TimeUnit.MINUTES);
            redisCacheTemplate.opsForValue().set(key + "EXPR", "111", 1, TimeUnit.MINUTES);
            return ServerResponse.createBySuccess("已向" + Util.repPhone(userDto.getMobile()) + "手机号成功发送验证码");
        }
        return ServerResponse.createByErrorMessage(serverResponse.getMsg());
    }

    @Override
    public ServerResponse forgetOperate(UserDto userDto) {
        String key = RedisKey.RESET_SMS_CODE + userDto.getUserInfo().getMobile();
        String smsCode = (String) redisCacheTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(smsCode)) {
            return ServerResponse.createByErrorMessage("验证码不存在");
        } else {
            if (!smsCode.equals(userDto.getSmsCode())) {
                return ServerResponse.createByErrorMessage("验证码错误");
            }
        }
        redisCacheTemplate.delete(key);
        User user = userCommonDao.findById(userDto.getUserInfo().getId());
        User u = new User();
        u.setId(user.getId());
        u.setOperatePassword(passwordEncoder.encode(userDto.getNewPassword()));
        userCommonDao.updatePwd(u);
        return ServerResponse.createBySuccess();
    }

    @Override
    public ServerResponse forgetLogin(UserDto userDto) {
        String key = RedisKey.RESET_SMS_CODE + userDto.getMobile();
        String smsCode = (String) redisCacheTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(smsCode)) {
            return ServerResponse.createByErrorMessage("验证码不存在");
        } else {
            if (!smsCode.equals(userDto.getSmsCode())) {
                return ServerResponse.createByErrorMessage("验证码错误");
            }
        }
        redisCacheTemplate.delete(key);
        User user = userCommonDao.findByMobile(userDto);
        User u = new User();
        u.setId(user.getId());
        u.setPassword(passwordEncoder.encode(userDto.getNewPassword()));
        userCommonDao.updatePwd(u);
        return ServerResponse.createBySuccess();
    }

    @Override
    public ServerResponse updateOpenId(UserDto userDto) {
        userDto.setOpenId(null);
        return ServerResponse.createBySuccess(userCommonDao.updateOpenId(userDto));
    }

    @Override
    public UserVo findOperatePasswordByUserId(Integer id) {
        return userCommonDao.findOperatePasswordByUserId(id);
    }

    /**
     * 根据openid查对应的运营账号
     *
     * @param unionId
     * @param status
     * @return
     */
    @Override
    public User getUserByUnionId(String unionId, Integer status) {

        return userCommonDao.getUserByUnionId(unionId, status);
    }

    /**
     * 微信公众号openID模拟账号密码登录
     *
     * @param user
     * @return
     */
    @Override
    public ServerResponse officialAccountSimulatedAccountLogin(User user) {
        return this.generateToken(user);
    }

    /**
     * 绑定微信公众号登录
     *
     * @param userDto
     * @return
     */
    @Override
    public ServerResponse bindWeChatOfficialAccountLogin(UserDto userDto) {

        if (org.springframework.util.StringUtils.isEmpty(userDto.getMobile())) {
            return ServerResponse.createByErrorMessage("请输入手机号");
        }

        if (org.springframework.util.StringUtils.isEmpty(userDto.getSmsCode())) {
            return ServerResponse.createByErrorMessage("请输入验证码");
        }

        if (org.springframework.util.StringUtils.isEmpty(userDto.getKey())) {
            return ServerResponse.createByErrorMessage("丢失key请联系平台客服");
        }

        //判断验证码
        String key = RedisKey.REGISTER_SMSCODE + userDto.getMobile();
        String s = (String) redisCacheTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(s)) {
            return ServerResponse.createByErrorMessage("验证码不存在");
        }

        if (!s.equals(userDto.getSmsCode())) {
            return ServerResponse.createByErrorMessage("验证码错误");
        }

        User user = (User) redisCacheTemplate.opsForValue().get(String.format(RedisKey.WAP_USER_TEMPORARY_WX_INFO, userDto.getKey()));
        if (org.springframework.util.StringUtils.isEmpty(user) || org.springframework.util.StringUtils.isEmpty(user.getUnionId())) {
            return ServerResponse.createByErrorMessage("绑定失败，请重新扫码绑定");
        }

        User existUser = userCommonDao.findUserByLoginUserName(userDto.getMobile(), UserStatusEnum.WRITE_OFF.getCode());
        if (org.springframework.util.StringUtils.isEmpty(existUser)) {
            return ServerResponse.createByErrorMessage("账号不存在");
        }

        User newUser = new User();
        newUser.setId(existUser.getId());
        newUser.setNickname(user.getNickname());
        newUser.setUnionId(user.getUnionId());
        newUser.setOpenId(user.getOpenId());
        int i = userCommonDao.update(newUser);
        if (i > 0) {

            ServerResponse serverResponse = this.officialAccountSimulatedAccountLogin(existUser);
            if (!serverResponse.getIsSuccess()) {
                ServerResponse.createByErrorMessage(serverResponse.getMsg());
            }

            String token = existUser.getToken();
            newUser = new User();
            newUser.setToken(token);
            return ServerResponse.createBySuccess(newUser);
        }
        return ServerResponse.createByErrorMessage("请重新点击绑定");
    }

    /**
     * 检查手机号是否已注册账号并绑定微信，有注册没绑定微信就发短信验证码
     *
     * @param userDto
     * @return
     */
    @Override
    public ServerResponse checkAccountExistAndBindWx(UserDto userDto) {
        /**
         * 错误码
         * 1000：其他错误，不需要业务判断
         * 1001：存在账号但未绑定微信
         */
        String key = RedisKey.REGISTER_SMSCODE + userDto.getMobile();

        User existUser = userCommonDao.findByMobile(userDto);

        // 账号没注册，继续正常注册
        if (org.springframework.util.StringUtils.isEmpty(existUser)) {
            return ServerResponse.createBySuccess();
        }

        // 账号有注册，但没有绑定微信登录
        if (!org.springframework.util.StringUtils.isEmpty(existUser.getOpenId()) && !org.springframework.util.StringUtils.isEmpty(existUser.getUnionId())) {
            return ServerResponse.createByErrorCodeMessage("1000", "该手机号已存在请更换新的号码");
        }

        return ServerResponse.createByErrorCodeMessage("1001", "该手机号已注册账号，但没有绑定微信登录。");
    }

    @Override
    public User getMobileAndUnionId(Integer id) {
        return userCommonDao.getMobileAndUnionId(id);
    }

    @Override
    public ServerResponse unbindMobileOrWeChat(UserDto userDto) {
        //先查，还要查操作密码
        User user = userCommonDao.findOperatePassword(userDto.getId());
        //解绑微信账号
        if ("wx".equals(userDto.getUnbindType())) {
            User userUpdate = new User();
            userUpdate.setId(userDto.getId());
            userUpdate.setUnionId(null);
            userCommonDao.updateWeXinAccount(userUpdate);
            return ServerResponse.createBySuccess("解绑微信账号成功");
        }
        //解绑手机号
        else if ("mobile".equals(userDto.getUnbindType())) {
            boolean isMatches = passwordEncoder.matches(userDto.getOperatePassword(), user.getOperatePassword());
            //校验操作密码
            if (!isMatches) {
                return ServerResponse.createByErrorMessage("操作密码不正确");
            }
            if (org.springframework.util.StringUtils.isEmpty(user.getUnionId())) {
                return ServerResponse.createByError("未绑定微信账号，无法解绑手机号");
            }
            User userUpdate = new User();
            userUpdate.setId(userDto.getId());
            userUpdate.setMobile(null);
            userCommonDao.updateMobile(userUpdate);
            return ServerResponse.createBySuccess("解绑手机号成功");
        } else {
            return ServerResponse.createByErrorMessage("不存在的解绑信息");
        }
    }

    @Override
    public ServerResponse updateUnionIdAndOpenId(UserDto userDto) {
        User str = (User) redisCacheTemplate.opsForValue().get(String.format(RedisKey.WAP_USER_TEMPORARY_WX_INFO, userDto.getK()));
        log.info("str：" + JSON.toJSONString(str));
        log.info("userDto：" + JSON.toJSONString(userDto));
        User user = new User();

        user.setId(userDto.getId());
        if (StringUtils.isEmpty(userDto.getK())) {
            user.setNickname("");
            user.setOfficialAccountOpenId("");
            userCommonDao.updateUnionIdAndOpenIdIsNull(user);
        } else {
            User userById = userCommonDao.findUserById(userDto.getId());
            if (!org.springframework.util.StringUtils.isEmpty(userById.getUnionId()) && !userById.getUnionId().equals(str.getUnionId())) {
                user.setUnionId(str.getUnionId());
            }

            user.setNickname(str.getNickname());
            user.setOfficialAccountOpenId(str.getOfficialAccountOpenId());
            userCommonDao.update(user);
        }
        userDto.setK("");
        return ServerResponse.createBySuccess();
    }

    @Override
    public ServerResponse updateUserInfo(UserDto userDto) throws Exception {
        if (StringUtils.isEmpty(userDto.getNickname())) {
            return ServerResponse.createByErrorMessage("微信昵称能为空");
        }
        if (StringUtils.isEmpty(userDto.getMobile())) {
            return ServerResponse.createByErrorMessage("手机号不能为空");
        }
        if (StringUtils.isEmpty(userDto.getUsername())) {
            return ServerResponse.createByErrorMessage("用户名称不能为空");
        }
        if (StringUtils.isEmpty(userDto.getPassword())) {
            return ServerResponse.createByErrorMessage("密码不能为空");
        }
        if (StringUtils.isEmpty(userDto.getHeadImgUrl())) {
            return ServerResponse.createByErrorMessage("头像不能为空");
        }
        User user = userCommonDao.findByMobile(userDto);
        if (ObjectUtils.isEmpty(user)) {
            //加密
            String password = passwordEncoder.encode(userDto.getPassword());
            userDto.setPassword(password);
            userCommonDao.update(userDto);
            BrandInfoVo brandInfoVo = brandInfoDao.findByUserId(userDto.getId());
            //更新手机号
            if (!ObjectUtils.isEmpty(brandInfoVo) && StringUtils.isEmpty(brandInfoVo.getServiceName())) {
                BrandInfoDto brandInfoDto = new BrandInfoDto();
                brandInfoDto.setServiceMobilePhone(userDto.getMobile());
                brandInfoDto.setId(brandInfoVo.getId());
                brandInfoDao.update(brandInfoDto);
            }
            CustomerServiceInfoDto customerServiceInfoDto = new CustomerServiceInfoDto();
            customerServiceInfoDto.setUserInfo(userDto.getUserInfo());
            List<CustomerServiceInfoVo> list = customerServiceInfoDao.findByUserIdList(customerServiceInfoDto);
            list.forEach(item -> {
                customerServiceInfoDto.setMerchantStoreId(item.getMerchantStoreId());
                customerServiceInfoDto.setServiceMobilePhone(userDto.getMobile());
                customerServiceInfoDto.setBrandInfoId(brandInfoVo.getId());
                CustomerServiceInfoVo customerServiceInfoVo = customerServiceInfoDao.findByMerchantStoreId(customerServiceInfoDto);
                if (ObjectUtils.isEmpty(customerServiceInfoVo)) {
                    //添加
                    customerServiceInfoDao.insertServiceMobilePhone(customerServiceInfoDto);
                } else {
                    //修改
                    customerServiceInfoDao.updateServiceMobilePhone(customerServiceInfoDto);
                }
            });
        } else {
            return ServerResponse.createByErrorCodeMessage("1000", "该手机号已注册账号！请联系平台客服处理！");
        }
        return ServerResponse.createBySuccess();
    }

    @Override
    public User findSubUserId(UserDto userDto) {
        return userCommonDao.findSubUserId(userDto);
    }

    @Override
    public Integer updateOfficialAccountOpenId(Integer userId, String officialAccountOpenId, Integer officialAccountId) {
        if (org.springframework.util.StringUtils.isEmpty(userId)) {
            throw new RuntimeException("userId不能为空");
        }
        if (org.springframework.util.StringUtils.isEmpty(officialAccountOpenId)) {
            throw new RuntimeException("officialAccountOpenId不能为空");
        }
        return userCommonDao.updateOfficialAccountOpenId(userId, officialAccountOpenId, officialAccountId);
    }

    @Override
    public ServerResponse findWhetherToSetWechatNotification(Integer id) {
        User user = userCommonDao.findById(id);
        if (ObjectUtils.isEmpty(user.getOfficialAccountOpenId())) {
            return ServerResponse.createByErrorMessage("绑定失败,请稍后再尝试");
        } else {
            return ServerResponse.createBySuccess();
        }
    }

    @Override
    public User getUserByOpenId(String openId, Integer status) {
        return userCommonDao.getUserByOpenId(openId, status);
    }

    @Override
    public ServerResponse sendSubscribe(UserDto userDto) {
        if (ObjectUtils.isEmpty(userDto.getCode())) {
            return ServerResponse.createByErrorMessage("code不能为空");
        }

        AppletOrOfficialAccount appletOrOfficialAccount = appletOrOfficialAccountCommonService.findOneByWeChatAppId(userDto.getAppId());

        if (ObjectUtils.isEmpty(appletOrOfficialAccount)) {
            return ServerResponse.createByErrorMessage("未找到微信小程序信息，APPID：" + userDto.getAppId());
        }
        final String jsCode2SessionJson = weChatAppletService.getJsCode2Session(userDto.getCode(), appletOrOfficialAccount.getWeChatAppId(), appletOrOfficialAccount.getWeChatAppSecret());
        if (ObjectUtils.isEmpty(jsCode2SessionJson)) {
            return ServerResponse.createByErrorMessage("获取openid有误");
        }
        final com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(jsCode2SessionJson);
        log.info(jsonObject.toJSONString());
        final String openid = jsonObject.getString("openid");
        final User user = userCommonDao.findUserById(userDto.getUserId());
        if (ObjectUtils.isEmpty(user)) {
            return ServerResponse.createByErrorMessage("获取信息错误");
        }
        log.info("openId：" + openid);
        userDto.setOpenId(openid);
        userDto.setAppletAccountId(appletOrOfficialAccount.getId());
        Integer result = userCommonDao.updateAppletAccountOpenId(userDto);
        if (result <= 0) {
            throw new RuntimeException("修改appletAccountOpenId错误");
        }
        return ServerResponse.createBySuccess();
    }

    @Override
    public ServerResponse findUserByMerchantStoreId(UserDto userDto) {
        return ServerResponse.createBySuccess(userCommonDao.findUserByMerchantStoreId(userDto));
    }

    /**
     * 添加或修改子账号权限
     *
     * @param userStoreDto
     * @return
     */
    @Override
    @Transactional
    public ServerResponse editUserRolePermission(UserStoreDto userStoreDto) {

        if (StringUtils.isEmpty(userStoreDto.getName())) {
            return ServerResponse.createByErrorMessage("名称不能为空");
        }

        if (ObjectUtils.isEmpty(userStoreDto.getRoleId())) {
            return ServerResponse.createByErrorMessage("新角色ID不能为空");
        }

        if (
                userStoreDto.getRoleId().equals(RoleEnum.SUPER_ADMINISTRATOR.getRoleId())
                        || userStoreDto.getRoleId().equals(RoleEnum.AGENT.getRoleId())
                        || userStoreDto.getRoleId().equals(RoleEnum.MERCHANT.getRoleId())
                        || userStoreDto.getRoleId().equals(RoleEnum.SUB_ACCOUNT.getRoleId())
                        || userStoreDto.getRoleId().equals(RoleEnum.FINANCE.getRoleId())
        ) {
            return ServerResponse.createByErrorMessage("RoleId：" + userStoreDto.getRoleId() + "有误");
        }

        if (ObjectUtils.isEmpty(userStoreDto.getStoreIdArray()) || userStoreDto.getStoreIdArray().length == 0) {
            return ServerResponse.createByErrorMessage("场地不能为空");
        }

        // 授权的权限ID集合
        List<Integer> inPermissionIdList = userStoreDto.getPermissionIdList();
        if (inPermissionIdList.size() > 0) {
            Permission permissionCondition = new Permission();
            permissionCondition.setOpenSetting(PermissionOpenSettingEnum.OPEN.getCode());
            permissionCondition.setStatus(PermissionStatusEnum.OPEN.getCode());
            permissionCondition.setUserInfo(userStoreDto.getUserInfo());
            final List<Permission> permissionList = permissionService.findAllPermissionByIdListAndOther(inPermissionIdList, permissionCondition);

            if (permissionList.size() != inPermissionIdList.size()) {
                inPermissionIdList = new ArrayList<>();
                for (Permission permission : permissionList) {
                    inPermissionIdList.add(permission.getId());
                }
            }
        }

        if (ObjectUtils.isEmpty(userStoreDto.getUserId())) {
            // 添加子账号
            if (StringUtils.isEmpty(userStoreDto.getMobile())) {
                return ServerResponse.createByErrorMessage("手机号不能为空");
            }
            if (StringUtils.isEmpty(userStoreDto.getPassword())) {
                return ServerResponse.createByErrorMessage("登录密码不能为空");
            }
            ServerResponse response = checkIsExist(userStoreDto.getMobile(), userStoreDto.getUsername());
            User user = new User();

            if (!response.getIsSuccess()) {
                return response;
            }

            user.setPassword(passwordEncoder.encode(userStoreDto.getPassword()));
            user.setOperatePassword(passwordEncoder.encode(userStoreDto.getPassword()));
            user.setMobile(userStoreDto.getMobile());
            user.setUsername(userStoreDto.getMobile());
            user.setAgencyId(userStoreDto.getUserInfo().getAgencyId());
            user.setStatus(AccountStatusEnum.NORMAL.getCode());
            user.setVersion(0);
            if (RoleEnum.SUB_ACCOUNT.getRoleId().equals(userStoreDto.getUserInfo().getRoleId())) {
                user.setParentId(userStoreDto.getUserInfo().getParentId());
            } else {
                user.setParentId(userStoreDto.getUserInfo().getId());
            }
            user.setWelfareReturnCoinSum(userStoreDto.getUserInfo().getWelfareReturnCoinSum());
            user.setName(userStoreDto.getName());
            userCommonDao.insert(user);

            // 商户自定义角色
            UserRole userRoleDiy = new UserRole();
            userRoleDiy.setRoleId(userStoreDto.getRoleId());
            userRoleDiy.setUserId(user.getId());
            userRoleService.add(userRoleDiy);

            // 平台固定角色
            UserRole userRole = new UserRole();
            userRole.setRoleId(RoleEnum.SUB_ACCOUNT.getRoleId());
            userRole.setUserId(user.getId());
            userRoleService.add(userRole);

            for (Integer storeId : userStoreDto.getStoreIdArray()) {
                UserAttribute userAttribute = new UserAttribute();
                userAttribute.setUserId(user.getId());
                userAttribute.setAttributeId(AttributeEnum.SUB_ACCOUNT_ADMIN_STORE.getCode());
                userAttribute.setMerchantStoreId(storeId);
                userAttribute.setNewStoreAutoAuthorization(userStoreDto.getNewStoreAutoAuthorization());
                userAttributeCommonService.insert(userAttribute);
            }

            if (userStoreDto.getNewStoreAutoAuthorization()) {
                // 新场地自动授权
                UserAttribute userAttribute = new UserAttribute();
                userAttribute.setUserId(user.getId());
                userAttribute.setAttributeId(AttributeEnum.NEW_STORES_ARE_AUTOMATICALLY_AUTHORIZED.getCode());
                userAttribute.setNewStoreAutoAuthorization(userStoreDto.getNewStoreAutoAuthorization());
                userAttributeCommonService.insert(userAttribute);
            }

            //查询角色权限功能
            List<UserPermission> addUserPermissionList = new ArrayList<>();
            for (Integer permissionId : inPermissionIdList) {
                UserPermission userPermission = new UserPermission();
                userPermission.setUserId(user.getId());
                userPermission.setPermissionId(permissionId);
                userPermission.setSelect(true);
                addUserPermissionList.add(userPermission);
            }

            if (addUserPermissionList.size() > 0) {
                userPermissionService.batchInsert(addUserPermissionList);
            }

        } else {
            // 修改子账号
            if (ObjectUtils.isEmpty(userStoreDto.getUserId())) {
                return ServerResponse.createByErrorMessage("缺少子账号ID");
            }

            if (ObjectUtils.isEmpty(userStoreDto.getUserRoleId())) {
                return ServerResponse.createByErrorMessage("缺少角色ID");
            }

            User subUser;
            if (userStoreDto.getUserInfo().getRoleId().equals(RoleEnum.SUB_ACCOUNT.getRoleId())) {
                if (userStoreDto.getUserInfo().getId().equals(userStoreDto.getUserId())) {
                    return ServerResponse.createByErrorMessage("子账号不能编辑自身权限");
                }

                UserDto userDtoCondition = new UserDto();
                UserInfo userInfo = userStoreDto.getUserInfo();
                userInfo.setId(userStoreDto.getUserInfo().getParentId());
                userDtoCondition.setUserInfo(userInfo);
                userDtoCondition.setUserId(userStoreDto.getUserId());
                subUser = userCommonDao.findSubUserId(userDtoCondition);
            } else {
                UserDto userDtoCondition = new UserDto();
                userDtoCondition.setUserInfo(userStoreDto.getUserInfo());
                userDtoCondition.setUserId(userStoreDto.getUserId());
                subUser = userCommonDao.findSubUserId(userDtoCondition);
            }
            if (org.springframework.util.StringUtils.isEmpty(subUser)) {
                return ServerResponse.createByErrorMessage("该子账号不存在");
            }

            //修改user表name
            UserDto userDto = new UserDto();
            userDto.setId(subUser.getId());
            userDto.setName(userStoreDto.getName());
            userCommonDao.updateName(userDto);

            /**
             * 修改userRole表角色-begin
             */
            // 先找到原来的自定义角色
            final UserRole userRole = userRoleService.findOneUserRoleByUserIdAndRoleType(subUser.getId(), RoleTypeEnum.MERCHANT.getCode());
            if (!org.springframework.util.StringUtils.isEmpty(userRole)) {
                if (!userRole.getRoleId().equals(userStoreDto.getRoleId())) {
                    UserRole updateUserRole = new UserRole();
                    updateUserRole.setId(userRole.getId());
                    updateUserRole.setRoleId(userStoreDto.getRoleId());
                    userRoleDao.update(updateUserRole);
                }
            } else {
                UserRole userRoleDiy = new UserRole();
                userRoleDiy.setRoleId(userStoreDto.getRoleId());
                userRoleDiy.setUserId(subUser.getId());
                userRoleService.add(userRoleDiy);
            }
            /**
             * 修改userRole表角色-end
             */

            /**
             * 修改授权场地-begin
             */
            UserDto userDto1 = new UserDto();
            userDto1.setUserId(subUser.getId());
            userDto1.setAttributeId(AttributeEnum.SUB_ACCOUNT_ADMIN_STORE.getCode());
            List<UserAttribute> userAttributeList = userAttributeCommonService.findUserAttributeByUserIdList(userDto1);

            // 原已授权的
            List<Integer> storeIdList = userAttributeList.stream()
                    .map(UserAttribute::getMerchantStoreId)
                    .collect(Collectors.toList());

            List<UserAttribute> userAttributesToInsert = new ArrayList<>();
            for (Integer storeId : userStoreDto.getStoreIdArray()) {
                // 如果当前 storeId 不在原已授权的列表中，则准备插入
                if (storeIdList.contains(storeId)) {
                    continue;
                }
                UserAttribute userAttribute = new UserAttribute();
                userAttribute.setUserId(subUser.getId());
                userAttribute.setAttributeId(AttributeEnum.SUB_ACCOUNT_ADMIN_STORE.getCode());
                userAttribute.setMerchantStoreId(storeId);
                userAttribute.setNewStoreAutoAuthorization(userStoreDto.getNewStoreAutoAuthorization());
                userAttributesToInsert.add(userAttribute);
            }
            // 批量插入新属性
            if (!userAttributesToInsert.isEmpty()) {
                userAttributeCommonService.batchInsert(userAttributesToInsert);
            }

            // 检查取消授权的
            List<Integer> storeIdNewList = new ArrayList<>();
            for (Integer i : userStoreDto.getStoreIdArray()) {
                storeIdNewList.add(i);
            }
            List<UserAttribute> userAttributesToDel = new ArrayList<>();
            for (UserAttribute userAttribute : userAttributeList) {
                if (storeIdNewList.contains(userAttribute.getMerchantStoreId())) {
                    continue;
                }
                userAttributesToDel.add(userAttribute);
            }

            // 批量删除
            if (!userAttributesToDel.isEmpty()) {
                userAttributeCommonService.batchDelete(userAttributesToDel);
            }

            if (!userAttributesToInsert.isEmpty() || !userAttributesToDel.isEmpty()) {
                // 授权场地ID有更新，需要删缓存，授权场地ID存在缓存中
                redisCacheTemplate.delete(String.format(RedisKey.WAP_USERINFO, subUser.getId()));
                redisCacheTemplate.delete(String.format(RedisKey.POS_USERINFO, subUser.getId()));
                redisCacheTemplate.delete(String.format(RedisKey.ADMIN_USERINFO, subUser.getId()));
            }
            /**
             * 修改授权场地-end
             */


            /**
             * 修改自动授权场地-begin
             */
            UserAttributeDto userAttributeDto = new UserAttributeDto();
            userAttributeDto.setAttributeId(AttributeEnum.NEW_STORES_ARE_AUTOMATICALLY_AUTHORIZED.getCode());
            userAttributeDto.setUserId(subUser.getId());
            final UserAttribute userAttributeExist = userAttributeCommonService.findAttributeAutoAuthorized(userAttributeDto);
            if (org.springframework.util.StringUtils.isEmpty(userAttributeExist)) {
                // 新场地自动授权
                UserAttribute userAttribute = new UserAttribute();
                userAttribute.setUserId(subUser.getId());
                userAttribute.setAttributeId(AttributeEnum.NEW_STORES_ARE_AUTOMATICALLY_AUTHORIZED.getCode());
                userAttribute.setNewStoreAutoAuthorization(userStoreDto.getNewStoreAutoAuthorization());
                userAttributeCommonService.insert(userAttribute);
            } else {
                UserAttribute userAttribute = new UserAttribute();
                userAttribute.setId(userAttributeExist.getId());
                userAttribute.setUserId(subUser.getId());
                userAttribute.setAttributeId(AttributeEnum.NEW_STORES_ARE_AUTOMATICALLY_AUTHORIZED.getCode());
                userAttribute.setNewStoreAutoAuthorization(userStoreDto.getNewStoreAutoAuthorization());
                userAttributeCommonService.update(userAttribute);
            }
            /**
             * 修改自动授权场地-end
             */


            /**
             * 更新权限-begin
             *
             * 新权限集合在对旧权限集合不存在的，用集合装起来批量插入
             *
             * 旧权限集合在新权限集合中不存在的，用集合装起来批量删除
             */
            // 授权记录
            List<UserPermission> beAuthorizedUserPermissionList = userPermissionService.findAllByUserId(subUser.getId());
            final List<Integer> oldPermissionIdList = beAuthorizedUserPermissionList.stream()
                    .map(UserPermission::getPermissionId)
                    .collect(Collectors.toList());

            // 新权限集合在对旧权限集合不存在的，用集合装起来批量插入
            List<UserPermission> addUserPermissionList = new ArrayList<>();
            for (Integer newPermissionId : inPermissionIdList) {
                if (!oldPermissionIdList.contains(newPermissionId)) {
                    UserPermission userPermission = new UserPermission();
                    userPermission.setUserId(subUser.getId());
                    userPermission.setPermissionId(newPermissionId);
                    userPermission.setSelect(true);
                    addUserPermissionList.add(userPermission);
                }
            }

            if (addUserPermissionList.size() > 0) {
                userPermissionService.batchInsert(addUserPermissionList);
            }

            // 旧权限集合在新权限集合中不存在的，用集合装起来批量删除
            List<UserPermission> delUserPermissionList = new ArrayList<>();
            for (Integer permissionId : oldPermissionIdList) {
                if (!inPermissionIdList.contains(permissionId)) {
                    UserPermission userPermission = new UserPermission();
                    userPermission.setUserId(subUser.getId());
                    userPermission.setPermissionId(permissionId);
                    delUserPermissionList.add(userPermission);
                }
            }
            if (delUserPermissionList.size() > 0) {
                userPermissionService.batchDelete(delUserPermissionList);
            }
            /**
             * 更新权限-end
             */

            redisCacheTemplate.delete(String.format(RedisKey.PERMISSION_USERID_V2, PermissionPlatformTypeEnum.PC_WEB_PAGE.getCode(), subUser.getId()));
            redisCacheTemplate.delete(String.format(RedisKey.PERMISSION_USERID_V2, PermissionPlatformTypeEnum.MERCHANT_APPLET.getCode(), subUser.getId()));
            redisCacheTemplate.delete(String.format(RedisKey.PERMISSION_USERID_V2, PermissionPlatformTypeEnum.CASHIER_DESK.getCode(), subUser.getId()));
            redisCacheTemplate.delete(String.format(RedisKey.PERMISSION_USERID_V2, PermissionPlatformTypeEnum.HAND_SIDE_OF_THE_CASHIER.getCode(), subUser.getId()));
        }

        return ServerResponse.createBySuccess();
    }

    @Override
    public ServerResponse finOneUserAndRoleUserByUserId(UserDto userDto) {
        if (org.springframework.util.StringUtils.isEmpty(userDto.getUserId())) {
            return ServerResponse.createByErrorMessage("子账号ID不能为空");
        }

        // 查询子账号信息
        UserDto userCondition = new UserDto();
        userCondition.setUserId(userDto.getUserId());
        userCondition.setRoleId(RoleEnum.SUB_ACCOUNT.getRoleId());
        UserVo userVo = userCommonDao.finOneUserAndRoleUserByUserId(userCondition);
        if (org.springframework.util.StringUtils.isEmpty(userVo)) {
            return ServerResponse.createByErrorMessage("子账号信息有误");
        }
        userVo.setRoleId(userVo.getRoleId());

        // 查询已授权场地信息
        UserDto uDto = new UserDto();
        uDto.setAttributeId(AttributeEnum.SUB_ACCOUNT_ADMIN_STORE.getCode());
        uDto.setUserId(userDto.getUserId());
        final List<UserAttribute> list = userAttributeCommonService.findUserAttributeByUserIdList(uDto);
        userVo.setUserAttributeList(list);

        // 查询新场地自动授权信息
        UserAttributeDto userAttributeDto = new UserAttributeDto();
        userAttributeDto.setAttributeId(AttributeEnum.NEW_STORES_ARE_AUTOMATICALLY_AUTHORIZED.getCode());
        userAttributeDto.setUserId(userDto.getUserId());
        final UserAttribute userAttribute = userAttributeCommonService.findAttributeAutoAuthorized(userAttributeDto);
        if (org.springframework.util.StringUtils.isEmpty(userAttribute)) {
            userVo.setNewStoreAutoAuthorization(false);
        } else {
            userVo.setNewStoreAutoAuthorization(userAttribute.getNewStoreAutoAuthorization());
        }

        userVo.setPassword(null);
        userVo.setOperatePassword(null);

        return ServerResponse.createBySuccess(userVo);
    }

    @Override
    public ServerResponse findSubAccountV2(User user) {
        UserDto userDto = new UserDto();
        userDto.setUserInfo(user.getUserInfo());
        userDto.setRoleId(RoleEnum.SUB_ACCOUNT.getRoleId());
        userDto.setPageNum(user.getPageNum());
        userDto.setPageSize(user.getPageSize());
        userDto.setStatus(UserStatusEnum.WRITE_OFF.getCode());
        userDto.setKeyword(user.getKeyword());
        PageHelper.startPage(userDto.getPageNum(), userDto.getPageSize());
        final List<User> list = userCommonDao.findSubAccountV2(userDto);
        PageInfo pagResult = new PageInfo(list);
        return ServerResponse.createBySuccess(pagResult);
    }

    @Override
    public ServerResponse deleteSubAccountByUserIdV2(UserDto userDto) {
        if (org.springframework.util.StringUtils.isEmpty(userDto.getUserId())) {
            return ServerResponse.createByError("子账号ID不能为空");
        }

        User subUser;
        if (userDto.getUserInfo().getRoleId().equals(RoleEnum.SUB_ACCOUNT.getRoleId())) {
            if (userDto.getUserInfo().getId().equals(userDto.getUserId())) {
                return ServerResponse.createByErrorMessage("子账号不能编辑自身权限");
            }

            UserDto userDtoCondition = new UserDto();
            UserInfo userInfo = userDto.getUserInfo();
            userInfo.setId(userDto.getUserInfo().getParentId());
            userDtoCondition.setUserInfo(userInfo);
            userDtoCondition.setUserId(userDto.getUserId());
            subUser = userCommonDao.findSubUserId(userDtoCondition);
        } else {
            UserDto userDtoCondition = new UserDto();
            userDtoCondition.setUserInfo(userDto.getUserInfo());
            userDtoCondition.setUserId(userDto.getUserId());
            subUser = userCommonDao.findSubUserId(userDtoCondition);
        }
        if (org.springframework.util.StringUtils.isEmpty(subUser)) {
            return ServerResponse.createByErrorMessage("该子账号不存在");
        }

        if (
                !userDto.getUserInfo().getRoleId().equals(RoleEnum.SUPER_ADMINISTRATOR.getRoleId())
                        && !userDto.getUserInfo().getRoleId().equals(RoleEnum.AGENT.getRoleId())
                        && !userDto.getUserInfo().getRoleId().equals(RoleEnum.MERCHANT.getRoleId())
        ) {
            return ServerResponse.createByError("非主账号不能删除子账号");
        }

        User updateUser = new User();
        updateUser.setId(subUser.getId());
        updateUser.setStatus(UserStatusEnum.WRITE_OFF.getCode());
        userCommonDao.update(updateUser);

        final Set<String> keys = redisHelper.keys(String.format(JwtRedisEnum.getKeyPrefix(subUser.getId())) + "*");
        redisCacheTemplate.delete(keys);

        return ServerResponse.createBySuccess("删除成功");
    }

}
